home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / reve / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  32.6 KB  |  948 lines

  1.  
  2. /*  @(#)main.c 1.25 91/11/13
  3.  *
  4.  *  Main routine for the reve program.
  5.  *
  6.  *  Copyright (C) 1990, 1991 - Rich Burridge & Yves Gallot.
  7.  *  All rights reserved.
  8.  *
  9.  *  Permission is granted to copy this source, for redistribution
  10.  *  in source form only, provided the news headers in "substantially
  11.  *  unaltered format" are retained, the introductory messages are not
  12.  *  removed, and no monies are exchanged.
  13.  *
  14.  *  Permission is also granted to copy this source, without the
  15.  *  news headers, for the purposes of making an executable copy by
  16.  *  means of compilation, provided that such copy will not be used
  17.  *  for the purposes of competition in any othello tournaments, without
  18.  *  prior permission from the authors.
  19.  *
  20.  *  No responsibility is taken for any errors on inaccuracies inherent
  21.  *  either to the comments or the code of this program, but if reported
  22.  *  (see README file), then an attempt will be made to fix them.
  23.  */
  24.  
  25. #include "reve.h"
  26. #include "color.h"
  27. #include "patchlevel.h"
  28. #include <ctype.h>
  29.  
  30. #ifdef X11
  31. #include <X11/Xos.h>
  32. #endif /*X11*/
  33.  
  34. #ifdef NO_TIMEVAL
  35. struct timeval {
  36.   long tv_sec ;         /* Seconds */
  37.   long tv_usec ;        /* Microseconds */
  38. } ;
  39. #endif /*NO_TIMEVAL*/
  40.  
  41. /*  Total amount of time (in minutes) to allow, at this level of difficulty.
  42.  *  The time allocation function is not used at level 1.
  43.  */
  44.  
  45. int timevals[MAXDIFF] = { 0, 1, 3, 5, 10, 15, 20, 30, 60 } ;
  46.  
  47. char *diff_values[]   = {
  48.   " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 ", NULL
  49. } ;
  50.  
  51. char *comp_plays[]    = { NULL, NULL, "neither", "both" } ;
  52. char *notes_values[]  = { "off", "on", NULL } ;
  53. char *player_values[] = { "human", "computer", NULL } ;
  54.  
  55. char *resources[] = {      /* Reve X resources read. */
  56.   "animate",               /* Boolean: show animation. */
  57.   "bestmove",              /* Boolean: show computer best move so far. */
  58.   "boardSize",             /* Integer: initial size of the reve game board. */
  59.   "showClocks",            /* Boolean: show clocks for each player. */
  60.   "difficulty",            /* Integer: difficulty level. */
  61.   "last",                  /* Boolean: show last move (with a square). */
  62.   "showLegalMoves",        /* Boolean: invalid moves shows legal moves. */
  63.   "log",                   /* Boolean: write computer info to log file. */
  64.   "notes",                 /* Boolean: show computer notes. */
  65.   "number",                /* Boolean: show last move (number on stone). */
  66.   "quick",                 /* Boolean: play quick game (don't flip stones). */
  67.   "panelColor",            /* String:  main and property panels color. */
  68.   "boardColor",            /* String:  playing board color. */
  69.   "boardBorderColor",      /* String:  playing board border color. */
  70.   "gridColor",             /* String:  grid lines color. */
  71.   "textColor",             /* String:  text color. */
  72.   "itemColor",             /* String:  color of the panel items. */
  73.   "blackStoneColor",       /* String:  "black" stone color. */
  74.   "whiteStoneColor",       /* String:  "white" stone color. */
  75.   "properties",            /* Boolean: initially show property window? */
  76.   "showHelp",              /* Boolean: initially show help window? */
  77.   "boldFont",              /* String:  bold font. */
  78.   "boardFont",             /* String:  game board font. */
  79.   "helpFont",              /* String:  help font. */
  80.   "normalFont",            /* String:  normal font. */
  81.   "blackStoneName",        /* String:  name for "black" stone messages. */
  82.   "whiteStoneName",        /* String:  name for "white" stone messages. */
  83.   "printCommand",          /* String:  command to use to print games. */
  84.   "iconiseForOpponentMove",  /* Boolean: close reve window for opponent move.*/
  85.   "bellAfterOpponentMove",   /* Boolean: sound bell after opponent move. */
  86.   "raiseAfterOpponentMove"   /* Boolean: raise window after opponent move. */
  87. } ;
  88.  
  89. enum cantype cmode, last_cmode ;
  90. enum disp_type dtype ;
  91. enum gr_type gtype ;        /* Graphics type. */
  92. enum set_type direction ;   /* Incremental direction for cycle item. */
  93. enum win_type curwin ;      /* Window the current event for in. */
  94.  
  95. FILE *hfp ;                 /* File descriptor for online help file. */
  96.  
  97. char *colstr[REVE_COLORSIZE] = {
  98.   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  99. } ;
  100.  
  101. int rcols[REVE_COLORSIZE] ;   /* Red colormap values. */
  102. int gcols[REVE_COLORSIZE] ;   /* Green colormap values. */
  103. int bcols[REVE_COLORSIZE] ;   /* Blue colormap values. */
  104.  
  105. int tx, ty, tw, th ;    /* Position and size of text field. */
  106.  
  107. int piece_x ;           /* Current X position of moving piece. */
  108. int piece_y ;           /* Current Y position of moving piece */
  109.  
  110. int bborder ;           /* Size of the reve game board border. */
  111. int best_cmove ;        /* Best computer move so far. */
  112. int board_height ;      /* Height of the reve game board in pixels. */
  113. int board_width ;       /* Width of the reve game board in pixels. */
  114. int but_inverted ;      /* Value of panel item inverted. */
  115. int cell_height ;       /* Height of an individual game board square. */
  116. int cell_width ;        /* Width of an individual game board square. */
  117. int cmove_depth ;       /* Depth of the current best computer move. */
  118. int color ;             /* Current color value. */
  119. int cur_ch ;            /* Current character pressed. */
  120. int curx ;              /* Current mouse X position. */
  121. int cury ;              /* Current mouse Y position. */
  122. int debug ;             /* If set, prints out various debug messages. */
  123. int down ;              /* Indicates is a mouse button is down. */
  124. int first_move = 0 ;    /* Set if computer plays first move. */
  125. int iconic ;            /* Set if window is currently iconic. */
  126. int help_height ;       /* Height of the help window. */
  127. int help_showing ;      /* If set, the help window is visible. */
  128. int help_width ;        /* Width of the help window. */
  129. int inv_video = 0 ;     /* Set if displaying in inverse video. */
  130. int invalid ;           /* Set if last move was invalid. */
  131. int isblack ;           /* Set if human to play the black pieces. */
  132. int iscolor ;           /* Set if this is a color screen. */
  133. int isremote ;          /* Set if playing remote user@host. */
  134. int iswhite ;           /* Set if human to play the white pieces. */
  135. int itemno ;            /* Current panel item being processed. */
  136. int item_value ;        /* Value for current panel item. */
  137. int ix ;                /* Initial X position of the icon. */
  138. int iy ;                /* Initial Y position of the icon. */
  139. int last_move ;         /* Last valid computer move. */
  140. int last_outline ;      /* Position of last piece outline whilst dragging. */
  141. int level ;             /* Current level of difficulty for computer moves. */
  142. int loadgame   = 0 ;    /* Set if there is a game file to load. */
  143. int lsval      = 0 ;    /* Set to 'l' or 's', if loading or saving. */
  144. int monochrome = 0 ;    /* If set, display will be in monochrome. */
  145. int move ;              /* Current move being evaluated. */
  146. int move_delta ;        /* Delta for piece animation. */
  147. int nextc ;             /* Current event identifier. */
  148. int next_player ;       /* Next player (BLACK or WHITE) to move. */
  149. int old_diffval ;       /* Old difficulty value (possibly restored). */
  150. int opp_bell ;          /* If set, sound bell after opponents move. */
  151. int opp_iconise ;       /* If set, close reve window for opponents move. */
  152. int opp_raise ;         /* If set, auto raise window after opponent move. */
  153. int pid ;               /* Process id of the reve_proc process. */
  154. int pieceXmargin ;      /* X margin between piece and cell width. */
  155. int pieceXrad ;         /* X radius of board piece. */
  156. int pieceYmargin ;      /* Y margin between piece and cell height. */
  157. int pieceYrad ;         /* Y radius of board piece. */
  158. int pipe_io[2][2] ;
  159. int play_computer ;     /* Set if playing against the computer. */
  160. int posspec ;           /* Set if -Wp or -g option is present (for X11) */
  161. int processing ;        /* If set, opponent is processing a move. */
  162. int props_showing ;     /* If set, the property window is visible. */
  163. int restore_moves ;     /* Indicates if legal moves should be reshown. */
  164. int saveres = 0 ;       /* If set, save computer results to log file. */
  165. int show_moves ;        /* If set, all possible moves are being shown. */
  166. int snote ;             /* Note value for current suggestion. */
  167. int socketfd ;          /* Socket no. for user@host. */
  168. int sstate ;            /* State of suggestion (showing/not showing). */
  169. int started ;           /* Set just before window is displayed. */
  170. int suggestion = -1 ;   /* Positive if a suggested move. */
  171. int tinput     = 0 ;    /* Set, when getting text input for load/save. */
  172. int validkey ;          /* Set if half way though a valid multiple key. */
  173. int wx ;                /* Initial X position of the window. */
  174. int wy ;                /* Initial Y position of the window. */
  175. int xdebug ;            /* If set, turns on debugging in the X11 driver. */
  176.  
  177. time_t last_btime ;     /* Last black time value. */
  178. time_t last_wtime ;     /* Last white time value. */
  179. time_t start_time ;     /* Start time for current move. */
  180.  
  181. int font_heights[MAXFONTS] ;     /* Height of all fonts used. */
  182. long help_offsets[MAXPAGES] ;    /* Offsets into the reve help file. */
  183.  
  184. /*  Globals for passing arguments to "sandwich";
  185.  *  this is to save time putting arguments on and off the
  186.  *  stack in a very heavily used piece of code
  187.  */
  188.  
  189. int s_flip ;
  190. int s_move ;
  191. int s_opponent ;
  192. int s_player ;
  193. int s_row ;
  194. int s_col ;
  195.  
  196. struct timeval tp ;        /* Used by the nap_upto routine. */
  197.  
  198. BOARD old_board ;          /* The previous reve board. */
  199. BOARD board ;              /* The current reve board. */
  200. BOARD *s_pos ;
  201. BOARD s_all ;              /* List of valid positions for this move. */
  202.  
  203. BOARD moves[64] ;          /* Complete array of board moves. */
  204.  
  205. struct iteminfo items[MAXITEMS] = {   /* Panel items. */
  206.  
  207. /*  wtype     type    lx    ly           Items for control panel window.
  208.  *  label
  209.  *  x         y
  210.  *  width     height  text  value
  211.  *  options   nopts
  212.  *  function
  213.  */
  214.  
  215.   {                                   /* load button. */
  216.     W_PANEL, P_BUTTON, 0, 0,
  217.     "",
  218.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  219.     BWIDTH, BHEIGHT, "load", 0,
  220.     (char **) NULL, 0,
  221.     draw_textfield
  222.   },
  223.  
  224.   {                                   /* moves? button. */
  225.     W_PANEL, P_BUTTON, 0, 0,
  226.     "",
  227.     BBORDER + (1*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  228.     BWIDTH, BHEIGHT, "moves?", 0,
  229.     (char **) NULL, 0,
  230.     show_all_moves
  231.   },
  232.  
  233.   {                                   /* new game button. */
  234.     W_PANEL, P_BUTTON, 0, 0,
  235.     "",
  236.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  237.     BWIDTH, BHEIGHT, "new game", 0,
  238.     (char **) NULL, 0,
  239.     new_game
  240.   },
  241.  
  242.   {                                   /* help button. */
  243.     W_PANEL, P_BUTTON, 0, 0,
  244.     "",
  245.     BBORDER + (3*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  246.     BWIDTH, BHEIGHT, "help...", 0,
  247.     (char **) NULL, 0,
  248.     do_help
  249.   },
  250.  
  251.   {                                   /* redo button. */
  252.     W_PANEL, P_BUTTON, 0, 0,
  253.     "",
  254.     BBORDER + (4*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  255.     BWIDTH, BHEIGHT, "redo", 0,
  256.     (char **) NULL, 0,
  257.     redo
  258.   },
  259.  
  260.   {                                   /* props button. */
  261.     W_PANEL, P_BUTTON, 0, 0,
  262.     "",
  263.     BBORDER + (5*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  264.     BWIDTH, BHEIGHT, "props...", 0,
  265.     (char **) NULL, 0,
  266.     do_props
  267.   },
  268.  
  269.   {                                   /* save button. */
  270.     W_PANEL, P_BUTTON, 0, 0,
  271.     "",
  272.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  273.     BWIDTH, BHEIGHT, "save", 0,
  274.     (char **) NULL, 0,
  275.     draw_textfield
  276.   },
  277.   
  278.   {                                   /* suggest button. */
  279.     W_PANEL, P_BUTTON, 0, 0,
  280.     "",
  281.     BBORDER + (1*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  282.     BWIDTH, BHEIGHT, "suggest", 0,
  283.     (char **) NULL, 0,
  284.     suggest
  285.   },
  286.   
  287.   {                                   /* print button. */
  288.     W_PANEL, P_BUTTON, 0, 0,
  289.     "",
  290.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  291.     BWIDTH, BHEIGHT, "print", 0,
  292.     (char **) NULL, 0,
  293.     print_game
  294.   },
  295.  
  296.  
  297.   {                                   /* stop button. */
  298.     W_PANEL, P_BUTTON, 0, 0,
  299.     "",    
  300. /*    BBORDER + (3*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)), */
  301.     -1, -1,
  302.     BWIDTH, BHEIGHT, "stop", 0,
  303.     (char **) NULL, 0,
  304.     do_stop
  305.   },
  306.  
  307.   {                                   /* undo button. */
  308.     W_PANEL, P_BUTTON, 0, 0,
  309.     "",
  310.     BBORDER + (4*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  311.     BWIDTH, BHEIGHT, "undo", 0,
  312.     (char **) NULL, 0,
  313.     undo
  314.   },
  315.   
  316.   {                                   /* cancel button. */
  317.     W_PANEL, P_BUTTON, 0, 0,
  318.     "",
  319.     -1, -1,                           /* Not normally active. */
  320.     BWIDTH, BHEIGHT, "cancel", 0,
  321.     (char **) NULL, 0,
  322.     remove_textfield
  323.   },
  324.   
  325.   {                                   /* quit button. */
  326.     W_PANEL, P_BUTTON, 0, 0,
  327.     "",
  328.     BBORDER + (5*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  329.     BWIDTH, BHEIGHT, "quit", 0,
  330.     (char **) NULL, 0,
  331.     destroy_reve
  332.   },
  333.   
  334.   {                                   /* Black player message item. */
  335.     W_PANEL, P_MESSAGE,
  336.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  337.     "Black:",
  338.     BBORDER + (1*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  339.     CWIDTH, CHEIGHT, "", 0,
  340.     (char **) NULL, 0,
  341.     NULL
  342.   },
  343.   
  344.   {                                   /* White player message item. */
  345.     W_PANEL, P_MESSAGE,
  346.     BBORDER + (3*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  347.     "White:",
  348.     BBORDER + (4*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  349.     CWIDTH, CHEIGHT, "", 1,
  350.     (char **) NULL, 0,
  351.     NULL
  352.   },
  353.  
  354.   {                                   /* Black player time left item. */
  355.     W_PANEL, P_CLOCK,
  356.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  357.     "Time left:",
  358.     BBORDER + (1*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  359.     0, 0, "", 1,
  360.     (char **) NULL, 0,
  361.     NULL
  362.   },
  363.  
  364.   {                                   /* White player time left item. */
  365.     W_PANEL, P_CLOCK,
  366.     BBORDER + (3*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  367.     "Time left:",
  368.     BBORDER + (4*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  369.     0, 0, "", 1,
  370.     (char **) NULL, 0,
  371.     NULL
  372.   },
  373.  
  374.   {                                   /* Panel message item. */
  375.     W_PANEL, P_MESSAGE, 0, 0,
  376.     "",
  377.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (4*(BHEIGHT+BGAP)),
  378.     0, 0, "Use left mouse button to move", 0,
  379.     (char **) NULL, 0,
  380.     NULL
  381.   },
  382.  
  383.   {                                   /* Notes message item. */
  384.     W_PANEL, P_MESSAGE, 0, 0,
  385.     "",
  386.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (5*(BHEIGHT+BGAP)),
  387.     0, 0, "", 0,
  388.     (char **) NULL, 0,
  389.     NULL
  390.   },
  391.  
  392.   {                                   /* Score message item. */
  393.     W_PANEL, P_MESSAGE, 0, 0,
  394.     "",
  395.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (6*(BHEIGHT+BGAP)),
  396.     0, 0, "Black:  2, White:  2", 0,
  397.     (char **) NULL, 0,
  398.     NULL
  399.   },
  400.  
  401.   {                                   /* Turn message item. */
  402.     W_PANEL, P_MESSAGE, 0, 0,
  403.     "",
  404.     BBORDER + (3*(BWIDTH+BGAP)), BBORDER + (6*(BHEIGHT+BGAP)),
  405.     0, 0, "", 0,
  406.     (char **) NULL, 0,
  407.     NULL
  408.   },
  409.  
  410. /*  wtype     type                    Property window items.
  411.  *  lx        ly
  412.  *  label
  413.  *  x         y
  414.  *  width     height  text  value
  415.  *  options   nopts
  416.  *  function
  417.  */
  418.  
  419.   {                                   /* Computer plays choice item. */
  420.     W_PROPS, P_CHOICE,
  421.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  422.     "Computer plays:",
  423.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (0*(BHEIGHT+BGAP)),
  424.     0, 0, "", 0,
  425.     (char **) comp_plays, 4,
  426.     set_option
  427.   },
  428.  
  429.   {                                   /* Difficulty choice item. */
  430.     W_PROPS, P_CHOICE,
  431.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  432.     "Difficulty:",
  433.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (1*(BHEIGHT+BGAP)),
  434.     0, 0, "", 0,
  435.     (char **) diff_values, 9,
  436.     set_option
  437.   },
  438.  
  439.   {                                   /* Set search depth cycle item. */
  440.     W_PROPS, P_CYCLE,
  441.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  442.     "Set search depth:",
  443.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (2*(BHEIGHT+BGAP)),
  444.     0, 0, "", 0,
  445.     (char **) NULL, 0,
  446.     set_option
  447.   },
  448.  
  449.   {                                   /* Options (Animate Move) item. */
  450.     W_PROPS, P_TOGGLE,
  451.     BBORDER + (0*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  452.     "Options:",
  453.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (3*(BHEIGHT+BGAP)),
  454.     TICKWIDTH, TICKHEIGHT, "Animate Move", 0,
  455.     (char **) NULL, 0,
  456.     set_option
  457.   },
  458.  
  459.   {                              /* Options (Show Current Best Move) item. */
  460.     W_PROPS, P_TOGGLE, 0, 0,
  461.     "",
  462.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (4*(BHEIGHT+BGAP)),
  463.     TICKWIDTH, TICKHEIGHT, "Show Current Best Move", 0,
  464.     (char **) NULL, 0,
  465.     set_option
  466.   },
  467.  
  468.   {                                   /* Options (Show Last Move) item. */
  469.     W_PROPS, P_TOGGLE, 0, 0,
  470.     "",
  471.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (5*(BHEIGHT+BGAP)),
  472.     TICKWIDTH, TICKHEIGHT, "Show Last Move", 0,
  473.     (char **) NULL, 0,
  474.     set_option
  475.   },
  476.  
  477.   {                              /* Options (Show Evaluation Info.) item. */
  478.     W_PROPS, P_TOGGLE, 0, 0,
  479.     "",
  480.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (6*(BHEIGHT+BGAP)),
  481.     TICKWIDTH, TICKHEIGHT, "Show Evaluation Info.", 0,
  482.     (char **) NULL, 0,
  483.     set_option
  484.   },
  485.  
  486.   {                                   /* Options (Number Last Move) item. */
  487.     W_PROPS, P_TOGGLE, 0, 0,
  488.     "",
  489.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (7*(BHEIGHT+BGAP)),
  490.     TICKWIDTH, TICKHEIGHT, "Number Last Move", 0,
  491.     (char **) NULL, 0,
  492.     set_option
  493.   },
  494.  
  495.   {                                   /* Options (Don't Show Flip) item. */
  496.     W_PROPS, P_TOGGLE, 0, 0,
  497.     "",
  498.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (8*(BHEIGHT+BGAP)),
  499.     TICKWIDTH, TICKHEIGHT, "Don't Show Flip", 0,
  500.     (char **) NULL, 0,
  501.     set_option
  502.   },
  503.  
  504.   {                    /* Options (Invalid Move Shows Legal Moves) item. */
  505.     W_PROPS, P_TOGGLE, 0, 0,
  506.     "",
  507.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (9*(BHEIGHT+BGAP)),
  508.     TICKWIDTH, TICKHEIGHT, "Invalid Move Shows Legal Moves", 0,
  509.     (char **) NULL, 0,
  510.     set_option
  511.   },
  512.  
  513.   {                    /* Options (Use clocks to time moves) item. */
  514.     W_PROPS, P_TOGGLE, 0, 0,
  515.     "",
  516.     BBORDER + (2*(BWIDTH+BGAP)), BBORDER + (10*(BHEIGHT+BGAP)),
  517.     TICKWIDTH, TICKHEIGHT, "Use Clocks to Time Moves", 0,
  518.     (char **) NULL, 0,
  519.     set_option
  520.   },
  521.  
  522.   {                                   /* Help window page cycle. */
  523.     W_HELP, P_CYCLE,
  524.     BBORDER + (0*(BWIDTH+BGAP)), CGAP,
  525.     "Page",
  526.     BBORDER + (1*(BWIDTH+BGAP)), CGAP,
  527.     0, 0, "", 1,
  528.     (char **) NULL, 0,
  529.     display_help
  530.   },
  531. } ;
  532.  
  533. char geometry[MAXLINE] ;       /* X11 geometry information. */
  534.  
  535. char *bstone_name ;            /* "Black" stone name for messages. */
  536. char *display = NULL ;         /* X11 display information. */
  537. char *fontnames[MAXFONTS] ;    /* Font names (via X resources). */
  538. char edgefile[MAXLINE] ;       /* Location of the reve edge table file. */
  539. char gamefile[MAXLINE] ;       /* Name of file for load/save. */
  540. char helpfile[MAXLINE] ;       /* Location of the reve online help file. */
  541. char line[40] ;
  542. char *myname ;                 /* user@host for this local person. */
  543. char *opponent ;               /* user@host for remote networked person. */
  544. char *printcommand ;           /* Command for printing the game. */
  545. char progname[MAXLINE] ;       /* The name of this program. */
  546. char reveproc[MAXLINE] ;       /* Pathname of the reve_proc program. */
  547. char *white_dpy ;              /* White piece display information. */
  548. char *wstone_name ;            /* "White" stone name for messages. */
  549.  
  550. /* REVE global variables */
  551.  
  552. int damier[NIVEAUMAX][64] ;  /* Boards at different depth level */
  553. int tacouleur, macouleur ;   /* Your and my colors during evaluation */
  554. int mnb, profmax ;           /* Number of moves played, current max. depth */
  555. int max_depth = 2 ;          /* Computer strategy - maximum depth. */
  556. int vp0, vo0 ;               /* Current mobility components */
  557. long c1, c2, c3 ;            /* Constants used in evaluation function */
  558. long edges[6561] ;           /* Edges Stability Table */
  559. long note ;                  /* Note value for current computer move. */
  560. time_t timeleft ;            /* Amount of time left for computer moves. */
  561.  
  562. extern enum gr_type gtype ;                     /* Graphics type. */ 
  563.  
  564.  
  565. int
  566. main(argc, argv)
  567. int argc ;
  568. char *argv[] ;
  569. {
  570.   STRCPY(progname, argv[0]) ;   /* Save program name for later use. */
  571.   STRCPY(gamefile, "reve.game") ;
  572.   SPRINTF(line, " Reve.  V1.3.%1d", PATCHLEVEL) ;
  573.   get_display(argc, argv) ;     /* Get possible X11 display information. */
  574.   init_graphics(&argc, argv) ;
  575.   reve_colorsetup(rcols, gcols, bcols) ;  /* Setup default colors. */
  576.   initialise() ;                /* Initialise variables used by reve. */
  577.   load_resources() ;            /* Get resources from various places. */
  578.   read_resources() ;            /* Read resources from merged database. */
  579.   get_options(argc, argv) ;     /* Read command line options. */
  580.   init_clocks() ;               /* Setup timer clocks. */
  581.   init_help_file(helpfile) ;    /* Load reve help file page offsets. */
  582.   set_display_types() ;         /* Work out what displays to initialise. */
  583.   if (init_ws_type())           /* Determine window system type. */
  584.     {
  585.       FPRINTF(stderr,"Error initialising window system.\n") ;
  586.       exit(1) ;
  587.     }
  588.   generate_graphics(argc, argv) ;
  589. #ifdef REMOTE_PLAYER
  590.   if (isremote)                 /* Do we need to get remote connection? */
  591.     {
  592.       get_addrs(myname, opponent) ;
  593.       open_ctl() ;
  594.       open_socket() ;
  595.       start_msgs() ;
  596.       if (is_local()) set_config(dtype) ;       /* Reconfigure. */
  597.       else            invite_remote() ;
  598.       end_msgs() ;
  599.       message(PANEL_MES, "Connection established") ;
  600.       beep() ;
  601.     }
  602. #endif /* REMOTE_PLAYER */
  603.   connect_io() ;
  604.   if (!isremote && dtype != XBOTH) load_and_move() ;
  605.   reset_clock(BLACK) ;
  606.   reset_clock(WHITE) ;
  607.   started = 1 ;
  608.   start_tool(dtype) ;           /* Event handling loop. */
  609.   exit(0) ;
  610. /*NOTREACHED*/
  611. }
  612.  
  613.  
  614. void
  615. do_opponent_move(player)
  616. int player ;
  617. {
  618.   set_cursor(CANVASCUR) ;
  619.   if (ANIMATION) animate_move(move) ;
  620.   if (best_cmove != -1 && DO_BESTMOVE) draw_square(best_cmove, IS_OFF, 2) ;
  621.   do_move(player) ;
  622.   last_move = move ;
  623.   cmode = (enum cantype) (OPPONENT(player) + 1) ;
  624. }
  625.  
  626.  
  627. void
  628. generate_graphics(argc, argv)
  629. int argc ;
  630. char *argv[] ;
  631. {
  632.   make_icon() ;
  633.   make_frame(argc, argv) ;        /* Create reve window/icon. */
  634.   init_fonts() ;                  /* Load normal and bold fonts. */
  635.   make_help_window(argc, argv) ;  /* Make help window based on normal font. */
  636.   make_canvas() ;                 /* Create drawing canvas. */
  637.   make_pieces(board_width, board_height) ;
  638.   initboard() ;
  639.   set_cursor(CANVASCUR) ;
  640. }
  641.  
  642.  
  643. void
  644. initialise()        /* Initialise various variable used by reve. */
  645. {
  646.   int i ;
  647.  
  648.   cury = wx = wy = ix = iy = 0 ;
  649.   bborder       = BBORDER ;
  650.   board_height  = BOARD_DIM ;         /* Initial board size. */
  651.   board_width   = BOARD_DIM ;
  652.   play_computer = 1 ;                 /* Default is human vs computer. */
  653.   iconic        = 0 ;                 /* Initially an open window. */
  654.   invalid       = FALSE ;
  655.   last_move     = -1 ;
  656.   last_outline  = -1 ;
  657.   next_player   = BLACK ;
  658.   best_cmove    = -1 ;
  659.   but_inverted  = -1 ;
  660.   debug         = FALSE ;
  661.   xdebug        = FALSE ;
  662.   help_showing  = FALSE ;    /* Help window not visible. */
  663.   opp_bell      = FALSE ;    /* Don't sound bell after opponents move. */
  664.   opp_iconise   = FALSE ;    /* Don't close reve window for opponents move. */
  665.   opp_raise     = FALSE ;    /* Don't auto raise window after opponent move. */
  666.   processing    = FALSE ;    /* No computer move initially. */
  667.   props_showing = FALSE ;    /* Properties window not visible. */
  668.   started       = FALSE ;
  669.   validkey      = 0 ;
  670.   cmode         = BLACK_START ;
  671.   show_moves    = FALSE ;
  672.   sstate        = IS_OFF ;
  673.   isblack       = 0 ;
  674.   isremote      = 0 ;
  675.   iswhite       = 0 ;
  676.   level         = INIT_DEPTH ;
  677.   items[(int) DIFF_CHOICE].value = old_diffval = level - 1 ;
  678.  
  679.   read_str(&myname, getuserhost()) ;      /* user@host for this person. */
  680.   opponent  = NULL ;                      /* No networked game by default. */
  681.  
  682.   pipe_io[0][0] = pipe_io[0][1] = pipe_io[1][0] = pipe_io[1][1] = -1 ;
  683.   socketfd      = -1 ;
  684.  
  685.   for (i = 0; i < MAXFONTS; i++) fontnames[i] = NULL ;
  686.  
  687.   read_str(&bstone_name,   "Black") ;     /* Default names for messages. */
  688.   read_str(&wstone_name,   "White") ;
  689.   read_str(&comp_plays[0], "white") ;     /* Computer plays: property item. */
  690.   read_str(&comp_plays[1], "black") ;
  691.   read_str(&printcommand,  "trans | lpr") ;      /* Default print command. */
  692.  
  693.   STRCPY(geometry, "") ;                  /* X11 geometry information. */
  694.   STRCPY(edgefile, EDGENAME) ;
  695.   STRCPY(helpfile, HELPNAME) ;
  696.   STRCPY(reveproc, REVEPROC) ;
  697. }
  698.  
  699.  
  700. void
  701. read_resources()            /* Read all possible resources from database. */
  702. {
  703.   int boolval, intval, len, n ;
  704.   char str[MAXLINE] ;
  705.  
  706.   if (get_bool_resource(R_ANIMATE,  &boolval)) ANIMATION   = boolval ;
  707.   if (get_bool_resource(R_BESTMOVE, &boolval)) DO_BESTMOVE = boolval ;
  708.  
  709.   if (get_int_resource(R_BOARDSIZE, &intval))
  710.     {
  711.       if (intval < MINBOARDSIZE) intval = MINBOARDSIZE ;
  712.       if (intval > MAXBOARDSIZE) intval = MAXBOARDSIZE ;
  713.       board_width = board_height = intval ;
  714.     }
  715.  
  716.   if (get_int_resource(R_DIFFICULTY, &intval))
  717.     {
  718.       level = intval ;
  719.       if (level < 1 || level > MAXDIFF) level = INIT_DEPTH ;
  720.       items[(int) DIFF_CHOICE].value = old_diffval = level - 1 ;
  721.     }
  722.  
  723.   if (get_bool_resource(R_CLOCK,     &boolval)) DO_CLOCK      = boolval ;
  724.   if (get_bool_resource(R_LAST,      &boolval)) DO_LAST       = boolval ;
  725.   if (get_bool_resource(R_LOG,       &boolval)) saveres       = boolval ;
  726.   if (get_bool_resource(R_LEGALMOVE, &boolval)) SHOW_LEGAL    = boolval ;
  727.   if (get_bool_resource(R_NOTES,     &boolval)) SHOW_NOTES    = boolval ;
  728.   if (get_bool_resource(R_NUMBER,    &boolval)) DO_NUMBER     = boolval ;
  729.   if (get_bool_resource(R_QUICK,     &boolval)) QUICKGAME     = boolval ;
  730.   if (get_bool_resource(R_PROPS,     &boolval)) props_showing = boolval ;
  731.   if (get_bool_resource(R_HELP,      &boolval)) help_showing  = boolval ;
  732.  
  733.   if (get_bool_resource(R_OPPICON,   &boolval)) opp_iconise   = boolval ;
  734.   if (get_bool_resource(R_OPPBELL,   &boolval)) opp_bell      = boolval ;
  735.   if (get_bool_resource(R_OPPRAISE,  &boolval)) opp_raise     = boolval ;
  736.  
  737.   if (get_str_resource(R_PANELC,  str)) read_str(&colstr[C_PANEL],  str) ;
  738.   if (get_str_resource(R_BOARDC,  str)) read_str(&colstr[C_SQUARE], str) ;
  739.   if (get_str_resource(R_BOARDBC, str)) read_str(&colstr[C_BORDER], str) ;
  740.   if (get_str_resource(R_GRIDC,   str)) read_str(&colstr[C_GRID],   str) ;
  741.   if (get_str_resource(R_TEXTC,   str)) read_str(&colstr[C_TEXT],   str) ;
  742.   if (get_str_resource(R_ITEMC,   str)) read_str(&colstr[C_ITEMS],  str) ;
  743.   if (get_str_resource(R_BSTONEC, str)) read_str(&colstr[C_BSTONE], str) ;
  744.   if (get_str_resource(R_WSTONEC, str)) read_str(&colstr[C_WSTONE], str) ;
  745.   if (get_str_resource(R_PCMD,    str)) read_str(&printcommand,     str) ;
  746.  
  747.   if (get_str_resource(R_BFONT, str)) read_str(&fontnames[(int) BFONT], str) ;
  748.   if (get_str_resource(R_GFONT, str)) read_str(&fontnames[(int) GFONT], str) ;
  749.   if (get_str_resource(R_HFONT, str)) read_str(&fontnames[(int) HFONT], str) ;
  750.   if (get_str_resource(R_NFONT, str)) read_str(&fontnames[(int) NFONT], str) ;
  751.  
  752.   if (get_str_resource(R_BSTONEN, str))
  753.     {
  754.       read_str(&bstone_name, str) ;
  755.       STRCPY(items[(int) BLACK_PLAYS].label, str) ;
  756.       len = strlen(str) ;
  757.       for (n = 0; n < len; n++)
  758.         if (isupper(str[n])) str[n] = tolower(str[n]) ; 
  759.       read_str(&comp_plays[1], str) ;
  760.     }
  761.   if (get_str_resource(R_WSTONEN, str))
  762.     {
  763.       read_str(&wstone_name, str) ;
  764.       STRCPY(items[(int) WHITE_PLAYS].label, str) ;
  765.       len = strlen(str) ;
  766.       for (n = 0; n < len; n++)
  767.         if (isupper(str[n])) str[n] = tolower(str[n]) ; 
  768.       read_str(&comp_plays[0], str) ;
  769.     }
  770. }
  771.  
  772.  
  773. void
  774. read_str(str, value)
  775. char **str, *value ;
  776. {
  777.   if (*str != NULL) (void) free(*str) ;
  778.   if (value != NULL && strlen(value))
  779.     {
  780.       *str = (char *) malloc((unsigned) (strlen(value) + 1)) ;
  781.       STRCPY(*str, value) ;
  782.     }
  783.   else *str = NULL ;
  784. }
  785.  
  786.  
  787. void
  788. set_config(dtype)
  789. enum disp_type dtype ;
  790. {
  791.   int val ;
  792.  
  793.   if (isremote)
  794.     if (dtype == XWHITE)
  795.       {
  796.         STRCPY(items[(int) BLACK_PLAYS].text, opponent) ;
  797.         STRCPY(items[(int) WHITE_PLAYS].text, myname) ;
  798.         processing = TRUE ;
  799.         set_cursor(HOURGLASS) ;
  800.       }
  801.     else
  802.       { 
  803.         STRCPY(items[(int) BLACK_PLAYS].text, myname) ;
  804.         STRCPY(items[(int) WHITE_PLAYS].text, opponent) ;
  805.       }
  806.      
  807.   isblack = iswhite = 0 ;
  808.        if (dtype == XBLACK) isblack = 1 ;
  809.   else if (dtype == XWHITE) iswhite = first_move = 1 ;
  810.   else if (dtype == XBOTH)  isblack = iswhite    = 1 ;
  811.      
  812.   val = (isblack == 0) ;
  813.   items[(int) BLACK_PLAYS].value = val ;
  814.   if (!isremote) STRCPY(items[(int) BLACK_PLAYS].text, player_values[val]) ;
  815.  
  816.   val = (iswhite == 0) ;
  817.   items[(int) WHITE_PLAYS].value = val ;
  818.   if (!isremote) STRCPY(items[(int) WHITE_PLAYS].text, player_values[val]) ;
  819.  
  820.        if (isremote)        items[(int) COMP_CHOICE].value = CP_NEITHER ;
  821.   else if (dtype == XBLACK) items[(int) COMP_CHOICE].value = CP_WHITE ;
  822.   else if (dtype == XWHITE) items[(int) COMP_CHOICE].value = CP_BLACK ;
  823.   else if (dtype == XBOTH)  items[(int) COMP_CHOICE].value = CP_NEITHER ;
  824. }
  825.  
  826.  
  827. /*  Work out, who plays what. There are a fair number of combinations.
  828.  *  This table hopefully gives the setup information for each combination.
  829.  *
  830.  *  NOTE: This could easily be done with less tests; instead the routine is
  831.  *        written for clarity.
  832.  *
  833.  *  | BLACK  WHITE   OPPONENT
  834.  *  |---------------------------
  835.  *  |A  -      -        -        black on local, white is computer.
  836.  *  |B  -      -     user@host   black on local, white on remote.
  837.  *  |C  -      -     computer    black on local, white is computer.
  838.  *  |D  -     SET       -        white on local, black is computer.
  839.  *  |E  -     SET    user@host   black on remote, white on local.
  840.  *  |F  -     SET    computer    black is computer, white is local.
  841.  *  |G SET     -        -        black on local, white is computer.
  842.  *  |H SET     -     user@host   black on local, white on remote.
  843.  *  |I SET     -     computer    black on local, white is computer.
  844.  *  |J SET    SET       -        both on local display.
  845.  *  |K SET    SET    user@host   black on local, white on remote.
  846.  *  |L SET    SET    computer    black on local, white is computer.
  847.  */
  848.  
  849. void
  850. set_display_types()
  851. {
  852.        if (!isblack && !iswhite && !opponent)                      /* A */
  853.     {
  854.       dtype    = XBLACK ;
  855.       isremote = 0 ;
  856.     }
  857.   else if (!isblack && !iswhite &&  opponent && !play_computer)    /* B */
  858.     {
  859.       dtype    = XBLACK ;
  860.       isremote = 1 ;
  861.     }
  862.   else if (!isblack && !iswhite &&  opponent &&  play_computer)    /* C */
  863.     {
  864.       dtype    = XBLACK ;
  865.       isremote = 0 ;
  866.     }
  867.   else if (!isblack &&  iswhite && !opponent)                      /* D */
  868.     {
  869.       dtype    = XWHITE ;
  870.       isremote = 0 ;
  871.     }
  872.   else if (!isblack &&  iswhite &&  opponent && !play_computer)    /* E */
  873.     {
  874.       dtype    = XWHITE ;
  875.       isremote = 1 ;
  876.     }
  877.   else if (!isblack &&  iswhite &&  opponent &&  play_computer)    /* F */
  878.     {
  879.       dtype    = XWHITE ;
  880.       isremote = 0 ;
  881.     }
  882.   else if ( isblack && !iswhite && !opponent)                      /* G */
  883.     {
  884.       dtype    = XBLACK ;
  885.       isremote = 0 ;
  886.     }
  887.   else if ( isblack && !iswhite &&  opponent && !play_computer)    /* H */
  888.     {
  889.       dtype    = XBLACK ;
  890.       isremote = 1 ;
  891.     }
  892.   else if ( isblack && !iswhite &&  opponent &&  play_computer)    /* I */
  893.     {
  894.       dtype    = XBLACK ;
  895.       isremote = 0 ;
  896.     }
  897.   else if ( isblack &&  iswhite && !opponent)                      /* J */
  898.     {
  899.       dtype    = XBOTH ;
  900.       isremote = 0 ;
  901.       play_computer = 1 ;
  902.     }
  903.   else if ( isblack &&  iswhite &&  opponent && !play_computer)    /* K */
  904.     {
  905.       dtype    = XBLACK ;
  906.       isremote = 1 ;
  907.     }
  908.   else if ( isblack &&  iswhite &&  opponent &&  play_computer)    /* L */
  909.     {
  910.       dtype    = XBLACK ;
  911.       isremote = 0 ;
  912.     }
  913.   set_config(dtype) ;
  914. }
  915.  
  916.  
  917. void
  918. usage()
  919. {
  920.   FPRINTF(stderr, "%s version 1.3.%1d\n\n", progname, PATCHLEVEL) ;
  921.   FPRINTF(stderr, "Usage: %s: [-animate] [-bestmove] ", progname) ;
  922.   FPRINTF(stderr, "[-black] [-clock] [-d difficulty]\n") ;
  923.   FPRINTF(stderr, "\t[-e edgefile] [-g geometry] [-h helpfile] [-help]\n") ;
  924.   FPRINTF(stderr, "\t[-i] [-last] [-load gamefile] [-log] [-m] [-notes]\n") ;
  925.   FPRINTF(stderr, "\t[-number] [-props] [-quick] [-r reve_proc] [-v]\n") ;
  926.   FPRINTF(stderr, "\t[-white] [-?] [-Wi] [-Wp x y] [-WP x y]\n") ;
  927. }
  928.  
  929.  
  930. #ifdef NO_USLEEP
  931. usleep(x)        /* Suspend execution for interval in microseconds. */
  932. unsigned x ;
  933. {
  934. #ifdef NOSELECT
  935.   unsigned seconds = x / 1000 ;
  936.  
  937.   if (x > 0) sleep(x) ;
  938. #else
  939.  
  940.   struct timeval st_delay ;
  941.  
  942.   st_delay.tv_usec = x ;
  943.   st_delay.tv_sec = 0 ;
  944.   (void) select(32, NULL, NULL, NULL, &st_delay) ;
  945. #endif /*NOSELECT*/
  946. }    
  947. #endif /*NO_USLEEP*/
  948.